package cn.baiduMap;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import com.baidu.location.BDAbstractLocationListener;
import com.baidu.location.BDLocation;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.CircleOptions;
import com.baidu.mapapi.map.InfoWindow;
import com.baidu.mapapi.map.LogoPosition;
import com.baidu.mapapi.map.MapPoi;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.Marker;
import com.baidu.mapapi.map.MarkerOptions;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.map.Overlay;
import com.baidu.mapapi.map.OverlayOptions;
import com.baidu.mapapi.map.PolylineOptions;
import com.baidu.mapapi.map.Stroke;
import com.baidu.mapapi.map.TextOptions;
import com.baidu.mapapi.map.UiSettings;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.model.LatLngBounds;
import com.baidu.mapapi.search.busline.BusLineResult;
import com.baidu.mapapi.search.busline.BusLineSearch;
import com.baidu.mapapi.search.busline.BusLineSearchOption;
import com.baidu.mapapi.search.busline.OnGetBusLineSearchResultListener;
import com.baidu.mapapi.search.core.PoiInfo;
import com.baidu.mapapi.search.core.SearchResult;
import com.baidu.mapapi.search.poi.OnGetPoiSearchResultListener;
import com.baidu.mapapi.search.poi.PoiBoundSearchOption;
import com.baidu.mapapi.search.poi.PoiCitySearchOption;
import com.baidu.mapapi.search.poi.PoiDetailResult;
import com.baidu.mapapi.search.poi.PoiDetailSearchResult;
import com.baidu.mapapi.search.poi.PoiIndoorResult;
import com.baidu.mapapi.search.poi.PoiNearbySearchOption;
import com.baidu.mapapi.search.poi.PoiResult;
import com.baidu.mapapi.search.poi.PoiSearch;
import com.baidu.mapapi.search.route.BikingRouteResult;
import com.baidu.mapapi.search.route.DrivingRouteLine;
import com.baidu.mapapi.search.route.DrivingRoutePlanOption;
import com.baidu.mapapi.search.route.DrivingRouteResult;
import com.baidu.mapapi.search.route.IndoorRouteResult;
import com.baidu.mapapi.search.route.MassTransitRouteResult;
import com.baidu.mapapi.search.route.OnGetRoutePlanResultListener;
import com.baidu.mapapi.search.route.PlanNode;
import com.baidu.mapapi.search.route.RoutePlanSearch;
import com.baidu.mapapi.search.route.TransitRouteLine;
import com.baidu.mapapi.search.route.TransitRoutePlanOption;
import com.baidu.mapapi.search.route.TransitRouteResult;
import com.baidu.mapapi.search.route.WalkingRouteLine;
import com.baidu.mapapi.search.route.WalkingRoutePlanOption;
import com.baidu.mapapi.search.route.WalkingRouteResult;

import java.util.ArrayList;
import java.util.List;

import overlayutil.BusLineOverlay;
import overlayutil.DrivingRouteOverlay;
import overlayutil.TransitRouteOverlay;
import overlayutil.WalkingRouteOverlay;

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    private MapView mMapView;
    private BaiduMap mBaiduMap;
    private LocationClient mLocationClient;
    private LatLng mlatLng;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initMap();
        POISearch();
        routePlan();
        MapEvents();
        initLocation();
    }

    //路线规划
    private void routePlan() {
        final RoutePlanSearch routePlanSearch = RoutePlanSearch.newInstance();
        routePlanSearch.setOnGetRoutePlanResultListener(new OnGetRoutePlanResultListener() {
            @Override
            public void onGetWalkingRouteResult(WalkingRouteResult walkingRouteResult) {
                WalkingRouteLine line = walkingRouteResult.getRouteLines().get(0);
                WalkingRouteOverlay overlay = new WalkingRouteOverlay(mBaiduMap);
                overlay.setData(line);
                overlay.addToMap();
                overlay.zoomToSpan();
            }

            @Override
            public void onGetTransitRouteResult(TransitRouteResult transitRouteResult) {
                TransitRouteLine line = transitRouteResult.getRouteLines().get(0);
                TransitRouteOverlay overlay = new TransitRouteOverlay(mBaiduMap);
                overlay.setData(line);
                overlay.addToMap();
                overlay.zoomToSpan();
            }

            @Override
            public void onGetMassTransitRouteResult(MassTransitRouteResult massTransitRouteResult) {

            }

            @Override
            public void onGetDrivingRouteResult(DrivingRouteResult drivingRouteResult) {
                DrivingRouteLine line = drivingRouteResult.getRouteLines().get(0);
                DrivingRouteOverlay overlay = new DrivingRouteOverlay(mBaiduMap);
                overlay.setData(line);
                overlay.addToMap();
                overlay.zoomToSpan();
            }

            @Override
            public void onGetIndoorRouteResult(IndoorRouteResult indoorRouteResult) {

            }

            @Override
            public void onGetBikingRouteResult(BikingRouteResult bikingRouteResult) {

            }
        });
        //步行路线
        findViewById(R.id.btn_WalkLine).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                PlanNode start = PlanNode.withLocation(new LatLng(23.188789185719386, 113.3608193901338));
                PlanNode end = PlanNode.withLocation(new LatLng(23.112520094213423, 113.33194785105265));
                routePlanSearch.walkingSearch(new WalkingRoutePlanOption().from(start).to(end));
            }
        });
        //市内公交路线
        findViewById(R.id.btn_BusLine).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                PlanNode start = PlanNode.withLocation(new LatLng(23.188789185719386, 113.3608193901338));
                PlanNode end = PlanNode.withLocation(new LatLng(23.112520094213423, 113.33194785105265));
                routePlanSearch.transitSearch(new TransitRoutePlanOption().from(start).to(end).city("广州"));
            }
        });
        //驾车路线
        findViewById(R.id.btn_DriveLine).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                PlanNode start = PlanNode.withLocation(new LatLng(23.188789185719386, 113.3608193901338));
                PlanNode end = PlanNode.withLocation(new LatLng(23.112520094213423, 113.33194785105265));
                routePlanSearch.drivingSearch(new DrivingRoutePlanOption().from(start).to(end));
            }
        });
    }

    //POI检索
    private void POISearch() {
        final PoiSearch mPoiSearch = PoiSearch.newInstance();
        mPoiSearch.setOnGetPoiSearchResultListener(new OnGetPoiSearchResultListener() {
            @Override
            public void onGetPoiResult(PoiResult poiResult) {
                List<PoiInfo> poiList = poiResult.getAllPoi();
                if (poiList != null) {
                    for (PoiInfo poiInfo : poiList) {
                        Log.e(TAG, poiInfo.toString());
                    }
                } else {
                    Log.e(TAG, "poiResult为空");
                }


                if (poiResult.error == SearchResult.ERRORNO.NO_ERROR) {
                    mBaiduMap.clear();

                    //创建PoiOverlay对象
                    PoiOverlay poiOverlay = new PoiOverlay(mBaiduMap);

                    //设置Poi检索数据
                    poiOverlay.setData(poiResult);

                    //将poiOverlay添加至地图并缩放至合适级别
                    poiOverlay.addToMap();
                    poiOverlay.zoomToSpan();
                }
            }

            @Override
            public void onGetPoiDetailResult(PoiDetailResult poiDetailResult) {

            }

            @Override
            public void onGetPoiDetailResult(PoiDetailSearchResult poiDetailSearchResult) {

            }

            @Override
            public void onGetPoiIndoorResult(PoiIndoorResult poiIndoorResult) {

            }
        });
        //POI城市检索
        findViewById(R.id.btn_POI_city).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mPoiSearch.searchInCity(new PoiCitySearchOption().city("广州").keyword("动物园").pageNum(10));
            }
        });
        //POI周边检索
        findViewById(R.id.btn_POI_nearby).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mlatLng != null) {
                    mPoiSearch.searchNearby(new PoiNearbySearchOption().location(mlatLng).radius(1000).keyword("餐厅").pageNum(10));
                } else {
                    Log.e(TAG, "latLng为空");
                }
            }
        });
        //POI区域检索
        findViewById(R.id.btn_POI_bound).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mlatLng != null) {
                    /**
                     * 设置矩形检索区域
                     */
                    LatLngBounds searchBounds = new LatLngBounds.Builder()
                            .include(new LatLng(mlatLng.latitude + 0.05, mlatLng.longitude - 0.05))
                            .include(new LatLng(mlatLng.latitude - 0.05, mlatLng.longitude + 0.05))
                            .build();

                    mPoiSearch.searchInBound(new PoiBoundSearchOption().bound(searchBounds).keyword("餐厅"));
                } else {
                    Log.e(TAG, "latLng为空");
                }
            }
        });
        //公交路线
        findViewById(R.id.btn_BusDetails).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //uid = c85bb9ec45db67f7704b87a4
                BusLineSearch busLineSearch = BusLineSearch.newInstance();
                busLineSearch.setOnGetBusLineSearchResultListener(new OnGetBusLineSearchResultListener() {
                    @Override
                    public void onGetBusLineResult(BusLineResult busLineResult) {
                        Log.e(TAG, busLineResult.toString());
                        BusLineOverlay busLineOverlay = new BusLineOverlay(mBaiduMap);
                        busLineOverlay.setData(busLineResult);
                        busLineOverlay.addToMap();
                        busLineOverlay.zoomToSpan();
                    }
                });
                busLineSearch.searchBusLine(new BusLineSearchOption().city("广州")
                        .uid("14a10620d139f925c8291551"));
            }
        });

    }

    //地图事件
    private void MapEvents() {
        //单击地图事件
        mBaiduMap.setOnMapClickListener(new BaiduMap.OnMapClickListener() {
            @Override
            public void onMapClick(LatLng latLng) {
                Log.e(TAG, "onMapClick: 纬度" + latLng.latitude + ",经度" + latLng.longitude);

//                drawRectangle(latLng);
//                drawCircle(latLng);
//                drawText(latLng);
//                drawInfoWindow(latLng);
            }

            @Override
            public boolean onMapPoiClick(MapPoi mapPoi) {
                Log.e(TAG, "onMapPoiClick: " + mapPoi.getName() + " 坐标 " + mapPoi.getPosition().toString());
                return false;
            }
        });
        //双击地图事件
        mBaiduMap.setOnMapDoubleClickListener(new BaiduMap.OnMapDoubleClickListener() {
            @Override
            public void onMapDoubleClick(LatLng latLng) {
                Log.e(TAG, "onMapDoubleClick:  纬度" + latLng.latitude + ",经度" + latLng.longitude);
            }
        });
        //长按地图事件
        mBaiduMap.setOnMapLongClickListener(new BaiduMap.OnMapLongClickListener() {
            @Override
            public void onMapLongClick(LatLng latLng) {
                Log.e(TAG, "onMapLongClick:  纬度" + latLng.latitude + ",经度" + latLng.longitude);
                //保存点击坐标
                mlatLng = latLng;

                //定义Maker坐标点
                LatLng point = new LatLng(latLng.latitude, latLng.longitude);
                //构建Marker图标
                BitmapDescriptor bitmap = BitmapDescriptorFactory
                        .fromResource(R.drawable.mark);
                //构建MarkerOption，用于在地图上添加Marker
                OverlayOptions option = new MarkerOptions()
                        .title("故宫")
                        .position(point)
                        .draggable(true)
                        .icon(bitmap);
                //在地图上添加Marker，并显示
                mBaiduMap.addOverlay(option);
            }
        });
        //标记点击事件
        mBaiduMap.setOnMarkerClickListener(new BaiduMap.OnMarkerClickListener() {
            @Override
            public boolean onMarkerClick(Marker marker) {
                Toast.makeText(MainActivity.this, marker.getTitle(), Toast.LENGTH_SHORT).show();
                return false;
            }
        });
    }

    //绘制信息窗
    private void drawInfoWindow(LatLng latLng) {
        //用来构造InfoWindow的Button
        Button button = new Button(getApplicationContext());
        button.setBackgroundResource(R.drawable.mark);
        button.setText("InfoWindow");

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.e(TAG, "mark被点击");
            }
        });
        //构造InfoWindow
        //point 描述的位置点
        //-100 InfoWindow相对于point在y轴的偏移量
        InfoWindow mInfoWindow = new InfoWindow(button, latLng, -100);

        //使InfoWindow生效
        mBaiduMap.showInfoWindow(mInfoWindow);
    }

    //绘制文本
    private void drawText(LatLng latLng) {
        //文字覆盖物位置坐标
        LatLng llText = new LatLng(latLng.latitude, latLng.longitude);

        //构建TextOptions对象
        OverlayOptions mTextOptions = new TextOptions()
                .text("百度地图SDK") //文字内容
                .bgColor(0xAAFFFF00) //背景色
                .fontSize(24) //字号
                .fontColor(0xFFFF00FF) //文字颜色
                .rotate(-30) //旋转角度
                .position(llText);

        //在地图上显示文字覆盖物
        Overlay mText = mBaiduMap.addOverlay(mTextOptions);
    }

    //绘制圆
    private void drawCircle(LatLng latLng) {
        //圆心位置
        LatLng center = new LatLng(latLng.latitude, latLng.longitude);

        //构造CircleOptions对象
        CircleOptions mCircleOptions = new CircleOptions().center(center)
                .radius(1400)
                .fillColor(0xAA0000FF) //填充颜色
                .stroke(new Stroke(5, 0xAA00ff00)); //边框宽和边框颜色

        //在地图上显示圆
        Overlay mCircle = mBaiduMap.addOverlay(mCircleOptions);
    }

    //绘制矩形
    private void drawRectangle(LatLng latLng) {
        //构建折线点坐标
        LatLng p1 = latLng;
        LatLng p2 = new LatLng(p1.latitude, p1.longitude + 0.05);
        LatLng p3 = new LatLng(p1.latitude + 0.05, p1.longitude + 0.05);
        LatLng p4 = new LatLng(p1.latitude + 0.05, p1.longitude);
        List<LatLng> points = new ArrayList<LatLng>();
        points.add(p1);
        points.add(p2);
        points.add(p3);
        points.add(p4);
        points.add(p1);

        //设置折线的属性
        OverlayOptions mOverlayOptions = new PolylineOptions()
                .width(10)
                .color(0xAAFF0000)
                .points(points);
        //在地图上绘制折线
        //mPloyline 折线对象
        Overlay mPolyline = mBaiduMap.addOverlay(mOverlayOptions);
    }

    //定位初始化
    private void initLocation() {
        mBaiduMap.setMyLocationEnabled(true);
        mLocationClient = new LocationClient(this);

        //通过LocationClientOption设置LocationClient相关参数
        LocationClientOption option = new LocationClientOption();
        option.setOpenGps(true); // 打开gps
        option.setCoorType("bd09ll"); // 设置坐标类型
        option.setScanSpan(1000);

        //设置locationClientOption
        mLocationClient.setLocOption(option);

        //设置定位图标和定位模式
//        MyLocationConfiguration myLocationConfiguration = new MyLocationConfiguration(MyLocationConfiguration.LocationMode.FOLLOWING, true
//                , BitmapDescriptorFactory.fromResource(R.mipmap.ic_launcher), 0xAAFFFF88, 0xAA00FF00);
//        mBaiduMap.setMyLocationConfiguration(myLocationConfiguration);

        //注册LocationListener监听器
        MyLocationListener myLocationListener = new MyLocationListener();
        mLocationClient.registerLocationListener(myLocationListener);
        //开启地图定位图层
        mLocationClient.start();
    }

    //初始化百度地图
    private void initMap() {
        //获取地图控件引用
        mMapView = (MapView) findViewById(R.id.bmapView);
        mBaiduMap = mMapView.getMap();

        //实例化UiSettings类对象
        UiSettings mUiSettings = mBaiduMap.getUiSettings();

        MapWidget(mUiSettings);
        MapGesture(mUiSettings);
    }

    //设置地图手势
    private void MapGesture(UiSettings mUiSettings) {
        //通过设置enable为true或false 选择是否启用地图平移
        mUiSettings.setScrollGesturesEnabled(true);
        //通过设置enable为true或false 选择是否启用地图缩放手势
        mUiSettings.setZoomGesturesEnabled(true);
        //通过设置enable为true或false 选择是否启用地图俯视功能
//        mUiSettings.setOverlookingGesturesEnabled(true);
        //通过设置enable为true或false 选择是否启用地图旋转功能
//        mUiSettings.setRotateGesturesEnabled(true);
        //通过设置enable为true或false 选择是否禁用所有手势
//        mUiSettings.setAllGesturesEnabled(false);
    }

    //设置地图控件
    private void MapWidget(UiSettings mUiSettings) {
        //设置地图logo
        mMapView.setLogoPosition(LogoPosition.logoPostionleftTop);

        //设置指南针,设置enable为true或false 选择是否显示指南针
        mUiSettings.setCompassEnabled(true);

        //设置比例尺,设置enable为true或false 选择是否显示比例尺
        mMapView.showScaleControl(true);
        //设置maxZoomLevel和minZoomLevel
        mBaiduMap.setMaxAndMinZoomLevel(0, 100);

        //设置缩放按钮，设置enable为true或false 选择是否显示缩放按钮
        mMapView.showZoomControls(true);

        //设置地图缩放级别
        mMapStatus();

        //隐藏地图标注，只显示道路信息
        //默认显示地图标注
        mBaiduMap.showMapPoi(true);
    }

    //设置地图缩放级别
    private void mMapStatus() {
        //直接缩放至缩放级别16
        mBaiduMap.setMapStatus(MapStatusUpdateFactory.zoomTo(16));
//        //使缩放级别增大一级
//        mBaiduMap.setMapStatus(MapStatusUpdateFactory.zoomIn());
//        //使缩放级别减小一级
//        mBaiduMap.setMapStatus(MapStatusUpdateFactory.zoomOut());
//        //在当前的缩放级别上增加或减小具体的缩放级别
//        // 4 在当前的缩放级别上增加4
//        mBaiduMap.setMapStatus(MapStatusUpdateFactory.zoomBy(4));
//        // -4 在当前的缩放级别上减小4
//        mBaiduMap.setMapStatus(MapStatusUpdateFactory.zoomBy(-4));
    }


    @Override
    protected void onResume() {
        super.onResume();
        //在activity执行onResume时执行mMapView. onResume ()，实现地图生命周期管理
        mMapView.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        //在activity执行onPause时执行mMapView. onPause ()，实现地图生命周期管理
        mMapView.onPause();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //在activity执行onDestroy时执行mMapView.onDestroy()，实现地图生命周期管理
        mLocationClient.stop();
        mBaiduMap.setMyLocationEnabled(false);
        mMapView.onDestroy();
        mMapView = null;
    }

    class MyLocationListener extends BDAbstractLocationListener {
        @Override
        public void onReceiveLocation(BDLocation location) {
            //mapView 销毁后不在处理新接收的位置
            if (location == null || mMapView == null) {
                return;
            }
            MyLocationData locData = new MyLocationData.Builder()
                    .accuracy(location.getRadius())
                    // 此处设置开发者获取到的方向信息，顺时针0-360
                    .direction(location.getDirection()).latitude(location.getLatitude())
                    .longitude(location.getLongitude()).build();
            mBaiduMap.setMyLocationData(locData);
        }
    }
}
